package com.rdgzs.framework.utilsTools;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * ###################################################
 * @创建日期：2013-5-26
 * @开发人员： 李广彬 
 * @功能描述：文件上传
 * 			1.文件缩为指定大小
 * 			2.文件按高度成比例缩放
 * 			3.文件按宽度成比例缩放
 * 			4.文件按指定的比例缩放
 * @修改日志： 
 * ###################################################
 */
public class ImageUploadUtils extends FileUploadUtils {
	public ImageUploadUtils() {
		
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：限制文件大小的上传---如果超过一定的大小则压缩或者限制上传
	* @传入参数：
	* @param uploadPath 上传目录 D:\Tools\apache-tomcat-6.0.37\work\Catalina\localhost\home
	* @param fileName 上传到服务器的文件名称 新的名字
	* @param orgPath 原始文件目录 D:\Tools\apache-tomcat-6.0.37\work\Catalina\localhost\home
	* @param orgFileName 文件路径 xxx.jpg 或 xxx 或 xxx\zzz.jpg
	* @param baseHeight 新文件高度 如果发null为默认为对像的原始高度
	* @param baseWidth 新文件宽度 如果发null为默认为对像的原始宽度
	* @throws IOException 
	*/
	public static boolean upLoad(
				String uploadPath, 
				String fileName, 
				String orgPath, 
				String orgFileName, 
				final Integer baseWidth,
				final Integer baseHeight
			) throws IOException {
		
		FileOutputStream out = null;
		String extension = ImageUploadUtils.getExtension(orgFileName);
		//取得服务器的文件，放入一个新的File对象当中
		String newFilePath = uploadPath  +File.separator+ fileName + "." + extension;
		String orgFilePath = orgPath +File.separator+ orgFileName;
		File newFile = new File(newFilePath);
		File orgFile = new File(orgFilePath);
		ImgSizeInfo imgInfo=new ImgSizeInfo(baseWidth,baseHeight);
		imgInfo=ImageUploadUtils.CalcImgSize(imgInfo,orgFile);
		return ImageUploadUtils.upLoad(newFile, orgFile,imgInfo.getWidth(), imgInfo.getHeight());
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：按 高度、宽度 成比例自适应缩放 
	* @传入参数：
	* @param uploadPath 上传目录 D:\Tools\apache-tomcat-6.0.37\work\Catalina\localhost\home
	* @param fileName 上传到服务器的文件名称 新的名字
	* @param orgFile 原始文件
	* @param baseWidth 图片缩放的基准宽度
	* @param baseHeight 图片缩放的基准高度
	*/
	public static Map upLoadScaling(
				final String uploadPath,
				final String fileName,
				final File orgFile,
				final Integer baseWidth,
				final Integer baseHeight
			) throws IOException {
		
		ImgSizeInfo imgInfo=new ImgSizeInfo(baseWidth,baseHeight);
		imgInfo=ImageUploadUtils.CalcImgSize(imgInfo,orgFile);
		Map resultMap=ImageUploadUtils.upLoad(uploadPath, fileName, orgFile, imgInfo.getWidth(),imgInfo.getHeight());
		resultMap=imgInfo.toMap(resultMap);
		return resultMap;
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：无限制文件上传
	* @传入参数：
	*/
	public static Map upLoad(String uploadPath, String fileName, File orgFile, final Integer width,final Integer height) throws IOException {
		Map resultMap=new HashMap();
		String extension = null;
		String newFilePath = null;
		if(ImageUploadUtils.hasExtension(fileName)){
			newFilePath = uploadPath +File.separator+ fileName;
		}else{
			extension = ImageUploadUtils.getExtension(orgFile.getName());
			newFilePath = uploadPath +File.separator+ fileName + "." + extension;
		}
		//取得服务器的文件，放入一个新的File对象当中
		File newFile = new File(newFilePath);
		boolean isSuccess=ImageUploadUtils.upLoad(newFile, orgFile, width,height);
		resultMap.put("filePath", newFilePath);
		resultMap.put("newFile", newFile);
		resultMap.put("isSuccess", isSuccess);
		resultMap.put("orgFile", orgFile);
		return resultMap;
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：无限制文件上传
	* @传入参数：
	*/
	public static boolean upLoad(File targetFile, File orgFile, final Integer width,final Integer height) throws IOException {
		boolean isSuccess = false;
		FileOutputStream out = null;
		String extension = ImageUploadUtils.getExtension(targetFile.getName());
		if (ImageUploadUtils.isImage(targetFile.getName())) {
			BufferedImage oimage = scaleImage(orgFile, height, width);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ImageIO.write(oimage, extension, bos);
			isSuccess = true;
			try {
				out = new FileOutputStream(targetFile);
				out.write(bos.toByteArray()); //写文件   
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (out != null) {
					out.close();
				}
			}
		}
		return isSuccess;
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：按高度成比例缩放
	* @传入参数：
	*/
	public static BufferedImage scaleImage(File newFile, final Integer height, final Integer width) throws IOException {
		Image img = ImageIO.read(newFile);
		BufferedImage imgBuffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Image scaleImg = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
		imgBuffer.getGraphics().drawImage(scaleImg, 0, 0, null);
		
		return imgBuffer;
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：加水印图片
	* @传入参数：String pressImg,水印图片;String targetImg,目标图片
	*/
	public static void pressImage(String pressImg, String targetImg, int x, int y) {
		try {
			File targetImgFile = new File(targetImg);
			File pressImgFile = new File(pressImg);
			pressImage(pressImgFile, targetImgFile, x, y);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：加水印图片
	* @传入参数：String pressImg,水印图片;String targetImg,目标图片
	*/
	public static void pressImage(File pressImgFile, File targetImgFile, int x, int y) {
		try {
			Image src = ImageIO.read(targetImgFile);
			int wideth = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
			Graphics g = image.createGraphics();
			g.drawImage(src, 0, 0, wideth, height, null);
			
			// 水印文件    
			Image watermarkImg = ImageIO.read(pressImgFile);
			int widethMark = watermarkImg.getWidth(null);
			int heightMark = watermarkImg.getHeight(null);
			g.drawImage(watermarkImg, wideth - widethMark - x, height - heightMark - y, widethMark, heightMark, null);
			g.dispose();
			jpegEncoder(targetImgFile, image);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：jped
	* @传入参数：
	*/
	public static void jpegEncoder(File targetImgFile, BufferedImage image) {
		try {
			FileOutputStream out = new FileOutputStream(targetImgFile);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(image);
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：图片格式校验
	* @传入参数：fileName 带有文件名的 文件路径
	*/
	public static Boolean isImage(final String fileName) throws IOException {
		Boolean flag = false;
		String extension = ImageUploadUtils.getExtension(fileName);
		Pattern pattern = Pattern.compile("bmp|gif|gepg|png|jpg");
		Matcher matcher = pattern.matcher(extension);
		if (matcher.find()) {
			flag = true;
		} else {
			flag = false;
		}
		return flag;
	}
	
	/**
	* @创建日期：2013-5-26
	* @开发人员：李广彬
	* @功能描述：图像尺寸初始化
	* @传入参数：
	* @param imgBaseInfo 
	* @param imgFile 
	*/
	public static ImgSizeInfo CalcImgSize(ImgSizeInfo imgBaseInfo,File imgFile) throws IOException  {
		Image img = ImageIO.read(imgFile);
		Integer imgHeight = img.getHeight(null);
		Integer imgWidth = img.getWidth(null);
		ImgSizeInfo imgInfo=new ImgSizeInfo(imgWidth,imgHeight);
		
		return ImageUploadUtils.CalcImgSize(imgBaseInfo,imgInfo,true);
	}
	
	public static Map CalcImgSize(Integer imgWidth,Integer imgHeight,Integer baseWidth,Integer baseHeight) {
		ImgSizeInfo imgInfo=new ImgSizeInfo(imgWidth,imgHeight);
		ImgSizeInfo imgBaseInfo=new ImgSizeInfo(baseWidth,baseHeight);
		imgInfo=ImageUploadUtils.CalcImgSize(imgBaseInfo,imgInfo,true);
		return imgInfo.toMap(new HashMap());
	}
	
	public static ImgSizeInfo CalcImgSize(ImgSizeInfo imgBaseInfo,ImgSizeInfo imgInfo,Boolean isFrist){
		Integer imgHeight = imgInfo.getHeight();
		Integer imgWidth = imgInfo.getWidth();
		Integer baseHeight = imgBaseInfo.getHeight();
		Integer baseWidth = imgBaseInfo.getWidth();
		
		if(baseHeight==null&&baseWidth==null){//原样大小
			imgInfo.setWidth(imgWidth);
			imgInfo.setHeight(imgHeight);
		}else{
			double scaling = 1;
			if (baseWidth!=null&&imgWidth > baseWidth) {//自适应宽
				scaling = baseWidth * 1.0 / imgWidth;
			}else if (baseHeight!=null&&imgHeight > baseHeight) {//自适应高
				scaling = baseHeight * 1.0 / imgHeight;
			} 
			Double height = imgHeight * scaling;
			Double width = imgWidth * scaling;
			imgInfo.setHeight(height.intValue());
			imgInfo.setWidth(width.intValue());
			if(imgInfo.getWidth()>imgBaseInfo.getWidth()||imgInfo.getHeight()>imgBaseInfo.getHeight()){
				imgInfo=ImageUploadUtils.CalcImgSize(imgBaseInfo,imgInfo,false);
			}
		}
		if(isFrist){
			imgInfo.setOrgHeight(imgHeight);
			imgInfo.setOrgWidth(imgWidth);
		}
		return imgInfo;
	}
	
	public static void main(String args[]) {
		Double k = 2 * 0.3;
		k.intValue();
		System.out.println(5 * 1.0 / 2);
	}
}

/**
 * ###################################################
 * @创建日期：2013-5-26
 * @开发人员： 李广彬 
 * @功能描述：图片计算 过程数据
 * @修改日志： 
 * ###################################################
 */
class ImgSizeInfo {
	private Integer width = null;//计算后的宽度
	private Integer height = null;//计算后的高度
	private Integer orgWidth = null;//原始宽度
	private Integer orgHeight = null;//原始高度
	private Double scaling = null;//缩放比
	private Double size = null;//图片大小

	public ImgSizeInfo() {

	}

	public ImgSizeInfo(Integer width, Integer height) {
		this.width = width;
		this.height = height;
	}
	
	public Map toMap(Map params) {
		params.put("width", width);
		params.put("height", height);
		params.put("orgWidth", orgWidth);
		params.put("orgHeight", orgHeight);
		params.put("scaling", scaling);
		params.put("size", size);
		return params;
	}

	public Integer getWidth() {
		return width;
	}

	public void setWidth(Integer width) {
		this.width = width;
	}

	public Integer getHeight() {
		return height;
	}

	public void setHeight(Integer height) {
		this.height = height;
	}

	public Double getSize() {
		return size;
	}

	public void setSize(Double size) {
		this.size = size;
	}

	public Integer getOrgWidth() {
		return orgWidth;
	}

	public void setOrgWidth(Integer orgWidth) {
		this.orgWidth = orgWidth;
	}

	public Integer getOrgHeight() {
		return orgHeight;
	}

	public void setOrgHeight(Integer orgHeight) {
		this.orgHeight = orgHeight;
	}

	public Double getScaling() {
		return scaling;
	}

	public void setScaling(Double scaling) {
		this.scaling = scaling;
	}

}
